package com.mate.cloud.redisson.service;

import jakarta.annotation.Resource;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 添加标签服务
 *
 * @author: MI
 * @email: 448341911@qq.com
 * @createTime: 2025/8/19 10:14
 * @updateUser: MI
 * @updateTime: 2025/8/19 10:14
 * @updateRemark: 修改内容
 * @version: 1.0
 */
@Service
public class TagService {

    @Resource
    private RedisTemplate<String, String> redisTemplate;


    private String tagKey(String tagName) {
        return "tag:" + tagName;
    }

    private String itemTagsKey(String itemId) {
        return "item:" + itemId + ":tags";
    }

    private String hotTagsKey() {
        return "tag:hot";
    }

    /**
     * 为商品添加标签
     *
     * @param itemId  商品ID
     * @param tagName 标签名称
     */
    public void addTagToItem(String itemId, String tagName) {
        // 1. 添加到标签的商品集合
        String tagKey = tagKey(tagName);
        redisTemplate.opsForSet().add(tagKey, itemId);

        // 2. 添加到商品的标签集合
        String itemTagsKey = itemTagsKey(itemId);
        redisTemplate.opsForSet().add(itemTagsKey, tagName);

        // 3. 更新标签热度
        String hotTagsKey = hotTagsKey();
        redisTemplate.opsForZSet().incrementScore(hotTagsKey, tagName, 1);

        // 4. 记录标签元数据（如果不存在）
        String metaKey = "tag:metadata:" + tagName;
        if (!redisTemplate.hasKey(metaKey)) {
            Map<String, String> metaData = new HashMap<>();
            metaData.put("createdAt", String.valueOf(System.currentTimeMillis()));
            metaData.put("createdBy", "system"); // 实际应为当前用户
            redisTemplate.opsForHash().putAll(metaKey, metaData);
        }
    }

    /**
     * 移除商品的标签
     *
     * @param itemId  商品ID
     * @param tagName 标签名称
     */
    public void removeTagFromItem(String itemId, String tagName) {
        // 1. 从标签的商品集合中移除
//        String tagKey = "tag:" + tagName;
        String tagKey = tagKey(tagName);
        redisTemplate.opsForSet().remove(tagKey, itemId);

        // 2. 从商品的标签集合中移除
//        String itemTagsKey = "item:" + itemId + ":tags";
        String itemTagsKey = itemTagsKey(itemId);
        redisTemplate.opsForSet().remove(itemTagsKey, tagName);

        // 3. 更新标签热度
        String hotTagsKey = hotTagsKey();
        redisTemplate.opsForZSet().incrementScore(hotTagsKey, tagName, -1);
    }


    /**
     * 执行标签清理
     */
    public int cleanupUnusedTags(int months) {
        String luaScript = "local period = tonumber(ARGV[1]) * 2592000 " +  // 2592000秒=30天
                "local cutoff = tonumber(redis.call('TIME')[1]) - period " +
                "local unusedTags = redis.call('ZRANGEBYSCORE', 'tag:last_used', '-inf', cutoff) " +
                "for _, tag in ipairs(unusedTags) do " +
                "    redis.call('DEL', 'tag:'..tag) " +
                "    redis.call('DEL', 'tag:metadata:'..tag) " +
                "    redis.call('ZREM', 'tag:hot', tag) " +
                "    redis.call('ZREM', 'tag:last_used', tag) " +
                "    redis.call('DEL', 'tag:autocomplete:'..tag) " +
                "end " +
                "return #unusedTags";

        return redisTemplate.execute(
                (RedisCallback<Integer>) connection -> connection.eval(
                        luaScript.getBytes(StandardCharsets.UTF_8),  // 显式指定编码，避免默认编码问题
                        ReturnType.INTEGER,
                        0,  // 脚本未使用 KEYS，故为 0
                        String.valueOf(months).getBytes(StandardCharsets.UTF_8)  // ARGV[1] 参数（仅1个，传递months的字节数组）
                )
        );
    }
}
